package p.ithorns.tools.excel.read;

import cn.idev.excel.EasyExcel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import p.ithorns.tools.excel.convert.Converters;
import p.ithorns.tools.excel.exception.ImportException;
import p.ithorns.tools.excel.model.ImportMultiSheetResult;
import p.ithorns.tools.excel.model.ImportSheetResult;
import p.ithorns.tools.excel.model.RowError;

import java.io.InputStream;
import java.util.*;

/**
 * MultiSheetImporter
 * 多页导入
 *
 * @author HtL
 * @date 2024/7/25 8:59
 * @since 1.0.0
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class MultiSheetImporter {

    private final static Logger log = LoggerFactory.getLogger(MultiSheetImporter.class);

    private MultiSheetImporter() {
    }


    /**
     * 导入
     * <p>
     * 多(页)处理器
     *
     * @param file     -导入文件
     * @param handlers -导入处理器
     * @return 导入结果
     */
    public static ImportMultiSheetResult doImport(MultipartFile file,
                                                  List<BaseImportHandler<?>> handlers) {
        // 1.校验参数
        if (Objects.isNull(file)) {
            throw new ImportException("MultipartFile对象为空, 上传处理失败");
        }

        // 2.进行导入  导入文件  解析、业务操作
        List<ImportSheetResult<?>> sheetResults = execute(file, handlers);

        ImportMultiSheetResult importMultiSheetResult = new ImportMultiSheetResult();
        importMultiSheetResult.setImportSheetResults(sheetResults);
        // 3.异常情况处理
        boolean hasError = sheetResults.stream().anyMatch(result -> result.getErrorCount() > 0);
        // 是否有异常数据
        importMultiSheetResult.setHasError(hasError);

        return importMultiSheetResult;
    }

    /**
     * 执行读取和导入
     *
     * @param file     -文件
     * @param handlers -导入处理器(多个)
     * @return 导入页结果列表
     */
    private static List<ImportSheetResult<?>> execute(MultipartFile file, List<BaseImportHandler<?>> handlers) {
        if (CollectionUtils.isEmpty(handlers)) {
            throw new ImportException("excel解析器为空, 上传处理失败");
        }

        List<ImportSheetResult<?>> sheetResults = new ArrayList<>();
        Map<String, Object> allCacheData = new HashMap<>(16);
        for (BaseImportHandler importHandler : handlers) {
            // 获取缓存参数
            importHandler.initCacheParamMap(allCacheData);
            try (InputStream inputStream = file.getInputStream()) {
                // 校验数据
                EasyExcel.read(inputStream)
                        .head(importHandler.getImportClass())
                        .sheet(importHandler.getSheetName())
                        .headRowNumber(importHandler.getHeadNumber())
                        .registerConverter(Converters.DATE_CONVERTER)
                        .registerConverter(Converters.DATE_TIME_CONVERTER)
                        .registerReadListener(importHandler)
                        .doRead();
            } catch (Exception e) {
                log.error("解析数据失败", e);
                // "解析校验数据失败, sheetName:" + importHandler.getSheetName()
                throw new ImportException(e.getMessage());
            }

            // 设置缓存参数 给后面流程使用
            Map<String, Object> curCacheData = importHandler.buildCacheParamMapForNext();
            if (MapUtils.isNotEmpty(curCacheData)) {
                allCacheData.putAll(curCacheData);
            }

            ImportSheetResult sheetResult = new ImportSheetResult<>(importHandler.getImportClass());
            // 设置sheet页名称
            sheetResult.setSheetName(importHandler.getSheetName());
            // 设置成功数量
            sheetResult.setSuccessCount(importHandler.getSuccessNum());
            // 错误信息列表
            List<RowError<?>> rowErrors = importHandler.getRowErrors();
            sheetResult.setRowErrors(rowErrors);
            sheetResult.setErrorCount(rowErrors.size());
            sheetResults.add(sheetResult);
        }

        return sheetResults;
    }

}